package com.gitee.qdbp.general.system.web.controlling.handler;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import com.gitee.qdbp.able.beans.AcceptAttrs;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.base.controlling.DataIsolationTools;
import com.gitee.qdbp.base.controlling.IAcceptAttrsHandler;
import com.gitee.qdbp.base.enums.OperateType;
import com.gitee.qdbp.base.system.model.IAccount;
import com.gitee.qdbp.base.utils.SessionTools;

/**
 * 数据隔离的数据权限属性处理
 *
 * @author zhaohuihua
 * @version 180612
 */
public abstract class AcceptAttrsSimpleHandler<T> implements IAcceptAttrsHandler {

    /** 弱控制容器 **/
    private List<String> weakAccepts;

    /** {@inheritDoc} **/
    @Override
    public AcceptAttrs<T> getAcceptAttrs(Object o, Field field, String dataType, OperateType operateType)
            throws ServiceException {

        if (!DataIsolationTools.using(field.getName())) { // 未启用数据隔离
            return null;
        }

        T value = getThreadAttrs(o, field, dataType, operateType);
        if (value == null) {
            IAccount user = DataIsolationTools.getAccount();
            if (user == null) {
                user = SessionTools.checkLoginUser();
            }
            if (user != null) {
                value = getUserAttrs(o, field, dataType, operateType, user);
            }
        }

        if (value == null) { // 取不到用户属性(一般是用户未登录)
            return getDefaultAcceptAttrs(o, field, dataType, operateType);
        } else {
            return getCurrentAcceptAttrs(o, field, dataType, operateType, value);
        }
    }

    /** 从当前线程变量中获取属性值 **/
    @SuppressWarnings("unchecked")
    protected T getThreadAttrs(Object o, Field field, String dataType, OperateType operateType) {
        return (T) DataIsolationTools.get(field.getName());
    }

    /** 根据登录用户获取属性值 **/
    protected abstract T getUserAttrs(Object o, Field field, String dataType, OperateType operateType, IAccount user);

    /** 获取当前登录用户的数据授权方式 **/
    protected abstract AcceptAttrs<T> getCurrentAcceptAttrs(Object o, Field field, String dataType,
            OperateType operateType, T userValue) throws ServiceException;

    /** 取不到用户属性(一般是用户未登录)时的数据授权方式 **/
    protected AcceptAttrs<T> getDefaultAcceptAttrs(Object o, Field field, String dataType, OperateType operateType)
            throws ServiceException {
        AcceptAttrs<T> attrs = new AcceptAttrs<>();
        attrs.setAll(true); // 未登录仍可访问的接口, 允许所有值
        attrs.setRequired(false);
        return attrs;
    }

    protected void setWeakAccepts(List<String> dataTypes) {
        this.weakAccepts = dataTypes;
    }

    protected void addWeakAccept(String dataType) {
        if (this.weakAccepts == null) {
            this.weakAccepts = new ArrayList<>();
        }
        this.weakAccepts.add(dataType);
    }

    protected boolean isWeakAccept(String dataType) {
        if (this.weakAccepts == null) {
            return false;
        }
        return this.weakAccepts.indexOf(dataType) >= 0;
    }
}
